{
 "metadata": {
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.4"
  },
  "orig_nbformat": 4,
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3.9.4 64-bit"
  },
  "interpreter": {
   "hash": "7ad59aab27c906dbbf0c2e1dfcaac35fb186b016969018ec3a977f4c21569b21"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2,
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd \n",
    "import numpy as np \n",
    "import matplotlib.pyplot as plt \n",
    "from scipy import stats\n",
    "plt.rcParams['font.family'] = 'SimHei'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "            group landing_page  converted\n",
       "0         control     old_page          0\n",
       "1         control     old_page          0\n",
       "2       treatment     new_page          0\n",
       "3       treatment     new_page          0\n",
       "4         control     old_page          1\n",
       "...           ...          ...        ...\n",
       "294473    control     old_page          0\n",
       "294474    control     old_page          0\n",
       "294475    control     old_page          0\n",
       "294476    control     old_page          0\n",
       "294477  treatment     new_page          0\n",
       "\n",
       "[294478 rows x 3 columns]"
      ],
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>group</th>\n      <th>landing_page</th>\n      <th>converted</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>control</td>\n      <td>old_page</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>control</td>\n      <td>old_page</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>treatment</td>\n      <td>new_page</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>treatment</td>\n      <td>new_page</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>control</td>\n      <td>old_page</td>\n      <td>1</td>\n    </tr>\n    <tr>\n      <th>...</th>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n    </tr>\n    <tr>\n      <th>294473</th>\n      <td>control</td>\n      <td>old_page</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>294474</th>\n      <td>control</td>\n      <td>old_page</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>294475</th>\n      <td>control</td>\n      <td>old_page</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>294476</th>\n      <td>control</td>\n      <td>old_page</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>294477</th>\n      <td>treatment</td>\n      <td>new_page</td>\n      <td>0</td>\n    </tr>\n  </tbody>\n</table>\n<p>294478 rows × 3 columns</p>\n</div>"
     },
     "metadata": {},
     "execution_count": 71
    }
   ],
   "source": [
    "data = pd.read_csv('./ab_data.csv')\n",
    "data = data[['group','landing_page','converted']]\n",
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [],
   "source": [
    "#数据分组\n",
    "#对照组\n",
    "control_group = data[(data.group=='control')&(data.landing_page=='old_page')]\n",
    "#实验组\n",
    "treatment_group = data[(data.group=='treatment')&(data.landing_page=='new_page')]\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "对照组：\n 均值(control_group_mean)：0.1203863045004612\n 方差(control_group_var)：0.10589417111639075\n 标准差(control_group_std)：0.3254138459199159\n 点击率(control_group_lv)：0.1203863045004612\n 统计数量(control_group_count)：145274\n"
     ]
    }
   ],
   "source": [
    "#对照组\n",
    "#统计数量\n",
    "control_group_count = control_group['converted'].count()\n",
    "#均值\n",
    "control_group_mean = control_group['converted'].mean()\n",
    "#方差\n",
    "control_group_var = control_group['converted'].var()\n",
    "#标准差\n",
    "control_group_std = control_group['converted'].std()\n",
    "#点击率\n",
    "# control_group_lv = control_group['converted']\n",
    "control_group_lv = control_group[(control_group.converted==1)]['converted'].count()/control_group['converted'].count()\n",
    "print('对照组：\\n 均值(control_group_mean)：{}\\n 方差(control_group_var)：{}\\n 标准差(control_group_std)：{}\\n 点击率(control_group_lv)：{}\\n 统计数量(control_group_count)：{}'.format(control_group_mean,control_group_var,control_group_std,control_group_lv,control_group_count))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "实验组\n 均值(treatment_group_mean)：0.11880724790277405\n 方差(treatment_group_var)：0.10469280622260349\n 标准差(treatment_group_std)：0.32356267742526096\n 点击率(treatment_group_lv)：0.11880724790277405\n 统计数量(treatment_group_count)：145311\n"
     ]
    }
   ],
   "source": [
    "#实验组\n",
    "#统计数量\n",
    "treatment_group_count = treatment_group['converted'].count()\n",
    "#均值\n",
    "treatment_group_mean = treatment_group['converted'].mean()\n",
    "#方差\n",
    "treatment_group_var = treatment_group['converted'].var()\n",
    "#标准差\n",
    "treatment_group_std = treatment_group['converted'].std()\n",
    "#点击率\n",
    "# control_group_lv = control_group['converted']\n",
    "treatment_group_lv = treatment_group[(treatment_group.converted==1)]['converted'].count()/treatment_group['converted'].count()\n",
    "print('实验组\\n 均值(treatment_group_mean)：{}\\n 方差(treatment_group_var)：{}\\n 标准差(treatment_group_std)：{}\\n 点击率(treatment_group_lv)：{}\\n 统计数量(treatment_group_count)：{}'.format(treatment_group_mean,treatment_group_var,treatment_group_std,treatment_group_lv,treatment_group_count))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "-0.0015790565976871451"
      ]
     },
     "metadata": {},
     "execution_count": 75
    }
   ],
   "source": [
    "#H1\t实验组 banner人均浏览量 – 对照组banner 人均浏览量\n",
    "diff_mean = treatment_group_mean-control_group_mean\n",
    "diff_mean"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [],
   "source": [
    "alpha = 0.05"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "1.4409481212379447e-06"
      ]
     },
     "metadata": {},
     "execution_count": 77
    }
   ],
   "source": [
    "#计算统计量\n",
    "varsum = treatment_group_var/treatment_group_count + treatment_group_var/treatment_group_count\n",
    "varsum"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "0.0"
      ]
     },
     "metadata": {},
     "execution_count": 78
    }
   ],
   "source": [
    "#P\n",
    "p = stats.norm.cdf(diff_mean,loc=2*control_group_std,scale=np.sqrt(varsum))\n",
    "p"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "实验结果没有原来好\n"
     ]
    }
   ],
   "source": [
    "#一类指标检验结果\n",
    "if p>0.05:\n",
    "    print('实验结果比原来要好')\n",
    "else:\n",
    "    print('实验结果没有原来好')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": [
      "实验组结果没有原来好\n"
     ]
    }
   ],
   "source": [
    "#二类指标检验结果\n",
    "if treatment_group_lv - control_group_lv > 0 :\n",
    "    print('实验组结果比原来要好')\n",
    "else:\n",
    "    print('实验组结果没有原来好')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [],
   "source": [
    "#封装\n",
    "def abtest(df: pd.DataFrame, alpha=0.05, group_col: str = None, value_col: str = None):\n",
    "    '''\n",
    "    :param df: 被分析DateFrame对象\n",
    "    :param alpha: 临界值\n",
    "    :param group_col: 组列的名字，默认为df的第一列\n",
    "    :param value_col: 值列的名字,默认为df的第2列\n",
    "    :return:best_group_name,pdf\n",
    "        best_group_name:最优组\n",
    "        pdf:最优组与其他组的差异性\n",
    "    '''\n",
    "    # 列名\n",
    "    if not group_col:\n",
    "        group_col = df.columns[0]\n",
    "    if not value_col:\n",
    "        value_col = df.columns[1]\n",
    "\n",
    "    # 寻找最优组与最优质值\n",
    "    best_group_name = df.groupby(group_col)[value_col].mean().sort_values(ascending=False).index.tolist()[0]\n",
    "    best_group_values = df[df[group_col] == best_group_name][value_col]  # 最优组的values\n",
    "    # 去除最优组的组名\n",
    "    group_names = list(set(df[group_col].unique().tolist()) - set(best_group_name))\n",
    "    # 初始化返回数据\n",
    "    pdf = pd.DataFrame(columns=[group_col,'mean', 'pvalue', 'ptype'])\n",
    "    # 计算差异性\n",
    "    for group_name in group_names:\n",
    "        group_values = df[df[group_col] == group_name][value_col]\n",
    "        \n",
    "        dif = best_group_values.mean() - group_values.mean()\n",
    "        var = best_group_values.var()/best_group_values.count() + group_values.var()/group_values.count()\n",
    "        std = best_group_values.std()\n",
    "      \n",
    "        pvalue =1-stats.norm.cdf(dif,loc=0.05,scale=np.sqrt(var))\n",
    "        \n",
    "        if pvalue >= alpha:\n",
    "            ptype = \"无显著差异\"\n",
    "        else:\n",
    "            ptype = \"有显著差异\"\n",
    "        # 添加数据\n",
    "        pdf.loc[pdf.shape[0]] = {group_col: group_name,'mean':group_values.mean(),  'pvalue': pvalue, 'ptype': ptype}\n",
    "\n",
    "    return best_group_name,best_group_values.mean(), pdf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [],
   "source": [
    "group_all = treatment_group[['group','converted']].append(control_group[['group','converted']])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": [
       "('control',\n",
       " 0.1203863045004612,\n",
       "        group      mean  pvalue  ptype\n",
       " 0    control  0.120386     1.0  无显著差异\n",
       " 1  treatment  0.118807     1.0  无显著差异)"
      ]
     },
     "metadata": {},
     "execution_count": 95
    }
   ],
   "source": [
    "abtest(group_all)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ]
}